package in.co.codedoc.config;

import java.lang.reflect.Method;

import in.co.codedoc.json.JSONObjectValue;
import in.co.codedoc.json.JSONUtil;
import in.co.codedoc.json.JSONValue;

public class ConfigurationUtil
{
	public static void ConfigureUsingProperties(Object object,JSONValue configData)
	{
		if(!(configData instanceof JSONObjectValue))
		{
			throw new RuntimeException
			(
				"Object scan be configured only by JSONObjectValues. Recieved '" +
				configData.getClass() + "' while configuring '" + object.getClass() + "'"
			);
		}
		
		Object decoded
			= JSONUtil.Decode((JSONObjectValue)configData, object.getClass().getCanonicalName());
		
		if(decoded == null)
		{
			throw new RuntimeException
			(
				"While configuring : Dont know how to json-decode a '" + object.getClass() + "'"
			);
		}
		
		Method copyMethod = null;
		
		try
		{
			copyMethod = object.getClass().getMethod("Copy", new Class[]{object.getClass()});
		}
		catch (Throwable th)
		{
			throw new RuntimeException
			(
				"Failed to lookup a Copy(" + object.getClass() + 
				") on class " + object.getClass() + ":" + th.getMessage(),
				th
			);
		}

		try
		{
			if(Logger.logger.isDebugEnabled())
			{
				Logger.logger.debug("Invoking " + copyMethod + " on a " + object.getClass() + ". Arg:" + decoded);
			}
			copyMethod.invoke(object, new Object[]{decoded});
		}
		catch (Throwable th)
		{
			throw new RuntimeException
			(
				"Failed to invoke Copy(" + object.getClass() + 
				") on class " + object.getClass() + ":" + th.getMessage(),
				th
			);
		}
	}
}
